import sys
import os
import unittest
from copy import deepcopy

sys.path.append("..")
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))

from framework.cmd_parser import CmdParser
from common.benchmark_var import StatusCode

# _BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))
# sys.path.append(_BASE_DIR)


class CmdParserTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.default_argv = deepcopy(sys.argv)
        cls.cmdparser = CmdParser()

    def setUp(self):
        pass

    def tearDown(self):
        sys.argv = deepcopy(self.default_argv)

    def _build_cmd_arguments(self, params):
        sys.argv = deepcopy(self.default_argv)
        sys.argv.extend(params)

    def test_empty(self):
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

    def test_test_target(self):
        param = ["-t", "ServerSuite"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()

        expect_options = {
            "action": None,
            "test_target": ["ServerSuite"],
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["--test_target", "ServerSuite"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["--benchmark", "ServerSuite"]
        self._build_cmd_arguments(param)

        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_action(self):
        param = ["-a", "build"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": "build",
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["--action", "build"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["--action", "rebuild"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_copies(self):
        param = ["-c", "1"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": 1,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["--copies", "1"]
        self._build_cmd_arguments(param)
        self.assertEqual(cmd_options, expect_options)

        param = ["--copies", "abcde"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_iteration(self):
        param = ["--iteration", "2"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": 2,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["-i", "2"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["-i", "abc"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_multithread(self):
        param = ["--multithread", "2"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": 2,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["-m", "2"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["-m", "abc"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_report(self):
        param = ["--report", "pdf", "all"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": ["pdf", "all"],
            "skip_fail": None,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["-r", "pdf", "txt"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options["report"] = ["pdf", "txt"]
        self.assertEqual(cmd_options, expect_options)

        param = ["-r", "json"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_output_dir(self):
        param = ["--output_dir", "work_dir"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": None,
            "output_dir": "work_dir",
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

    def test_skip_fail(self):
        param = ["--skipfail", "1"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": 1,
            "debug": None,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["-s", "1"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["-s", "2"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_debug(self):
        param = ["--debug", "1"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        expect_options = {
            "action": None,
            "test_target": None,
            "copies": None,
            "iterations": None,
            "multithread": None,
            "config": "config_sample.ini",
            "report": None,
            "skip_fail": None,
            "debug": 1,
            "output_dir": None,
            "help": False,
            "version": False
        }
        self.assertEqual(cmd_options, expect_options)

        param = ["-d", "1"]
        self._build_cmd_arguments(param)
        cmd_options = self.cmdparser.parse()
        self.assertEqual(cmd_options, expect_options)

        param = ["-d", "2"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.OPTION_PARSE_FAIL)

    def test_version(self):
        param = ["--version"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.SUCCESS)

        param = ["-v"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.SUCCESS)

    def test_help(self):
        param = ["--help"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.SUCCESS)

        param = ["-h"]
        self._build_cmd_arguments(param)
        try:
            self.cmdparser.parse()
        except SystemExit as e:
            self.assertEqual(e.code, StatusCode.SUCCESS)


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(CmdParserTestCase)
    unittest.TextTestRunner(verbosity=2).run(suite)












